//----------------cnet includes------------------
#include <cnet.h>
#include <cnetsupport.h>
//-----------------------------------------------

#include "transport_layer/tr_common.c"

//-------------------sending---------------------
#include "link_layer/dl_sending.c"
#include "network_layer/nw_sending.c"
#include "transport_layer/tr_sending.c"
//-----------------------------------------------



//------------------receiving--------------------
#include "transport_layer/tr_receiving.c"
#include "network_layer/nw_receiving.c"
#include "link_layer/dl_receiving.c"
//-----------------------------------------------


//function called on node startup
void reboot_node(CnetEvent ev, CnetTimerID timer, CnetData data)
{	
	
	/*
	 *-------------<<<<HANDLER>>>>-------------
	 */
	//send handler
	CHECK(CNET_set_handler(EV_APPLICATIONREADY, TR_msg_read, 0));
	
	//receive handler
	CHECK(CNET_set_handler(EV_PHYSICALREADY, DL_receive_frame, 0));
	
	//timeout handler
	CHECK(CNET_set_handler( EV_TIMER1, DL_timeouts, 0));
	
	CHECK(CNET_set_handler(EV_TIMER2,NW_reboot_timeouts,0));
	
	CHECK(CNET_set_handler(TR_ACK_TIMER,TR_ack_timeouts,0));

	CHECK(CNET_set_handler(EV_TIMER4,NW_routing_updates,0));

	//CHECK(CNET_set_handler( EV_DRAWFRAME, draw_frame, 0));
	
	/*
	 *---------------<<<<INIT TRANSPORT LAYER>>>>---------------
	 */
	dest_nodes = vector_new();
	src_nodes = vector_new();

	/*
	 *---------------<<<<INIT NETWORK LAYER>>>>---------------
	 */
	 
	 ht_destinations = hashtable_new(0); //initializing the routing hash table (destination, outgoing link)
	 a_avail_destinations = vector_new();
	 a_ht_dest_link_costs = (HASHTABLE*) calloc(nodeinfo.nlinks, sizeof(HASHTABLE));	 
	 
	/*
	 *---------------<<<<INIT LINK LAYER>>>>---------------
	 */

	a_out_link_data = (OUT_LINK_DATA*) calloc(nodeinfo.nlinks, sizeof(OUT_LINK_DATA));
	a_inc_link_data = (INC_LINK_DATA*) calloc(nodeinfo.nlinks, sizeof(INC_LINK_DATA));
	

	/*
	 *---------------<<<<INIT LOOP>>>>---------------
	 */
	for(unsigned int link = 1; link <= nodeinfo.nlinks; ++link) {

		link_cost_table(link) = hashtable_new(0);
		
		OUT_LINK_DATA* iter_out =	&a_out_link_data[link - 1];
		iter_out->infolen =			0;			
		iter_out->s_max_chunk =		0;		
		iter_out->c_curr_part =		0;		
		iter_out->f_pkt_finished =	1;		
		iter_out->f_link_ready =	1;		
		iter_out->c_total_parts =	0;		
		iter_out->s_last_chunk =	0;		
		iter_out->buffer = queue_new();
		iter_out->S_BUFFER =		100; 		//might be determined dynamically (e.g., based on throughput, mtu, ...)
		iter_out->lasttimer =		NULLTIMER;
		iter_out->link_cost =		1; 		
		iter_out->seq =				1; 			//will be computed by a weighting function
		
		
		INC_LINK_DATA* iter_inc =	&a_inc_link_data[link - 1];
		iter_inc->c_curr_part = 0;
		iter_inc->infolen = 0;
		iter_inc->s_max_chunk = linkinfo[link].mtu - FRAME_HEADER_SIZE;
		iter_inc->seq =				1; 		
		
	}
	
	reboot_timer1 = 1; 						//discovery packets begin
	reboot_timer2 = (CnetTime) 100000000;	//first iteration end
	routing_timer = (CnetTime) 10000000;	//first routing update

    CNET_start_timer(EV_TIMER2,reboot_timer1, 0);
	CNET_start_timer(EV_TIMER2,reboot_timer2, 2);
CNET_start_timer(EV_TIMER4,routing_timer, 0);
}
